/*
GANESHA - Reasoning on critical infrastructures affected by emergency situations
Copyright (c) 2010-2011, Information Eng. Research Unit - Univ. of Alcala
http://www.cc.uah.es/ie
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free
Software Foundation; either version 2.1 of the License, or (at your option)
any later version.
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
details.
You should have received a copy of the GNU Lesser General Public License along
with this library; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package es.uah.cc.ie.ganesha.messaging.position;

/**
 * Represents a circular position.
 * @author ieru
 */
public class CirclePosition extends MessagePosition {

	private double _centerLatitude, _centerLongitude;
	private double _radius;

	/**
	 * Constructor.
	 * @param centerLatitude Center latitude
	 * @param centerLongitude Center longitude
	 * @param radius Circle radius (in Kilometer)
	 */
	public CirclePosition(double centerLatitude, double centerLongitude, double radius) {
		_centerLatitude = centerLatitude;
		_centerLongitude = centerLongitude;

		_radius = radius;
	}

	/**
	 * Returns the circle's center latitude.
	 * @return Circle's center latitude.
	 */
	@Override
	public double getCenterLatitude() {
		return _centerLatitude;
	}

	/**
	 * Returns the circle's center longitude.
	 * @return Circle's center longitude.
	 */
	@Override
	public double getCenterLongitude() {
		return _centerLongitude;
	}

	/**
	 * Returns the circle radius.
	 * @return Circle radius.
	 */
	public double getRadius() {
		return _radius;
	}

	/**
	 * Returns true if the given point is in the circle area.
	 * @param latitude
	 * @param longitude
	 * @return True if the given point is in the circle area, false if not.
	 */
	@Override
	public boolean isInArea(double latitude, double longitude) {
		final double earthRadius = 6371f;
		double dLat = 0f, dLon = 0f;
		double a = 0f, c = 0f, d = 0f;
		double lon1 = _centerLongitude, lat1 = _centerLatitude;
		double lon2 = longitude, lat2 = latitude;
		
		dLat = Math.toRadians(lat2 - lat1);
		dLon = Math.toRadians(lon2 - lon1);

		a = Math.sin(dLat / 2.0) * Math.sin(dLat / 2.0) +
				Math.cos(lat1) * Math.cos(lat2) *
				Math.sin(dLon / 2.0) * Math.sin(dLon / 2.0);

		c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
		d = earthRadius * c;

		return (d < _radius);
	}
}
